package ui.troopmanager.mooresr.us;

import java.awt.Color;
import java.awt.Cursor;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.Date;
import java.util.LinkedList;

import javax.swing.Box;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JTextField;

import troopmanager.mooresr.us.DataManager;
import troopmanager.mooresr.us.Event;
import troopmanager.mooresr.us.EventSpecialFormName;
import troopmanager.mooresr.us.GoogleMaps;
import troopmanager.mooresr.us.Person;

import com.toedter.calendar.JDateChooser;

public class EventDetailDialog extends JDialog {
	private static final long serialVersionUID = 1L;

	private JLabel eventNameLabel = new JLabel("Event Name:");
	private JTextField eventNameText = new JTextField(20);
	private JLabel departureLocationLabel = new JLabel("Departure Location:");
	private JTextField departureLocationText = new JTextField(20);
	private JLabel destinationLabel = new JLabel("Destination:");
	private JTextField destinationText = new JTextField(20);
	private JLabel departureDateLabel = new JLabel("Departure Date:");
	private JDateChooser departureDateChooser = new JDateChooser();
	private JLabel returnDateLabel = new JLabel("Return Date:");
	private JDateChooser returnDateChooser = new JDateChooser();
	private JLabel permitFiledLabel = new JLabel("Permit filed:");
	private JCheckBox permitFiledCheckBox = new JCheckBox();
	private JLabel swimmingLabel = new JLabel("Swimming:");
	private JCheckBox swimmingCheckBox = new JCheckBox();
	private JLabel boatingLabel = new JLabel("Boating:");
	private JCheckBox boatingCheckBox = new JCheckBox();
	private JLabel climbingLabel = new JLabel("Climbing:");
	private JCheckBox climbingCheckBox = new JCheckBox();
	private JLabel flyingLabel = new JLabel("Flying:");
	private JCheckBox flyingCheckBox = new JCheckBox();
	private JLabel highAdventureLabel = new JLabel("High Adventure:");
	private JCheckBox highAdventureCheckBox = new JCheckBox();
	private JLabel travelMilesLabel = new JLabel("Travel Miles:");
	private JTextField travelMilesText = new JTextField(5);
	private JButton calculateButton = new JButton("Lookup Distance");
	private JLabel tourLeaderLabel = new JLabel("Tour Leader:");
	private JComboBox tourLeaderComboBox = new JComboBox();
	private JLabel tourLeaderAgeLabel = new JLabel("Age: ");
	private JLabel asstTourLeaderLabel = new JLabel("Assistant Leader:");
	private JComboBox asstTourLeaderComboBox = new JComboBox();
	private JLabel asstTourLeaderAgeLabel = new JLabel("Age: ");
	private JLabel specialFormsLabel = new JLabel("Special Forms: ");
	private DefaultListModel specialFormsListModel = new DefaultListModel();
	private JList specialFormsList = new JList(specialFormsListModel);
	private JButton editSpecialFormsButton = new JButton("Edit List");
	private JButton okButton = new JButton("OK");
	private JButton cancelButton = new JButton("Cancel");
	
	private Integer eventId;
	private Boolean isNew;
	
	

	
	public EventDetailDialog() {
		initComponents();
	}
	
	private void initComponents() {
		GridBagLayout layout = new GridBagLayout();
		
		setTitle("Edit/Add Event");
		setFont(new Font("Dialog", Font.PLAIN, 12));
		setBackground(Color.white);
		setForeground(Color.black);
		
		// Constraints used for the labels in the first column
		GridBagConstraints labelConstraints = new GridBagConstraints();
		labelConstraints.gridx = 0;
		labelConstraints.gridy = GridBagConstraints.RELATIVE;  // Next row
		labelConstraints.anchor = GridBagConstraints.LINE_END;
		labelConstraints.ipadx = 16;
		
		// Constraints for (most of) the controls in the second column
		GridBagConstraints controlConstraints = new GridBagConstraints();
		controlConstraints.gridx = 1;
		controlConstraints.gridy = GridBagConstraints.RELATIVE;  // Next row
		controlConstraints.anchor = GridBagConstraints.LINE_START;
		controlConstraints.ipadx = 16;
		
		// Constraints for wide controls in the second column
		GridBagConstraints wideControlConstraints = new GridBagConstraints();
		wideControlConstraints.gridx = 1;
		wideControlConstraints.gridy = GridBagConstraints.RELATIVE;  // Next row
		wideControlConstraints.anchor = GridBagConstraints.LINE_START;
		wideControlConstraints.ipadx = 16;
		wideControlConstraints.gridwidth = 2;
		
		// Constraints for controls in the third column
		GridBagConstraints thirdColumnControlConstraints = new GridBagConstraints();
		thirdColumnControlConstraints.gridx = 2;
		thirdColumnControlConstraints.gridy = GridBagConstraints.RELATIVE;  // Next row
		thirdColumnControlConstraints.anchor = GridBagConstraints.LINE_START;
		thirdColumnControlConstraints.ipadx = 16;
		
		setLayout(layout);
		
		add(eventNameLabel, labelConstraints);

		add(eventNameText, wideControlConstraints);

		add(departureLocationLabel, labelConstraints);

		add(departureLocationText, wideControlConstraints);

		add(destinationLabel, labelConstraints);

		add(destinationText, wideControlConstraints);

		add(departureDateLabel, labelConstraints);

		add(departureDateChooser, wideControlConstraints);

		add(returnDateLabel, labelConstraints);

		add(returnDateChooser, wideControlConstraints);

		add(permitFiledLabel, labelConstraints);

		add(permitFiledCheckBox, controlConstraints);
		
		add(Box.createVerticalGlue(), thirdColumnControlConstraints);

		add(swimmingLabel, labelConstraints);

		add(swimmingCheckBox, controlConstraints);
		
		add(Box.createVerticalGlue(), thirdColumnControlConstraints);

		add(boatingLabel, labelConstraints);

		add(boatingCheckBox, controlConstraints);
		
		add(Box.createVerticalGlue(), thirdColumnControlConstraints);

		add(climbingLabel, labelConstraints);

		add(climbingCheckBox, controlConstraints);
		
		add(Box.createVerticalGlue(), thirdColumnControlConstraints);

		add(flyingLabel, labelConstraints);

		add(flyingCheckBox, controlConstraints);
		
		add(Box.createVerticalGlue(), thirdColumnControlConstraints);

		add(highAdventureLabel, labelConstraints);

		add(highAdventureCheckBox, controlConstraints);
		
		add(Box.createVerticalGlue(), thirdColumnControlConstraints);

		add(travelMilesLabel, labelConstraints);

		add(travelMilesText, controlConstraints);

		add(calculateButton, thirdColumnControlConstraints);

		add(tourLeaderLabel, labelConstraints);

		add(tourLeaderComboBox, controlConstraints);
		
		add(tourLeaderAgeLabel, thirdColumnControlConstraints);

		add(asstTourLeaderLabel, labelConstraints);

		add(asstTourLeaderComboBox, controlConstraints);
		
		add(asstTourLeaderAgeLabel, thirdColumnControlConstraints);
		
		add(specialFormsLabel, labelConstraints);
		
		add(specialFormsList, controlConstraints);
		
		add(editSpecialFormsButton, thirdColumnControlConstraints);

		add(okButton, labelConstraints);

		add(cancelButton, controlConstraints);
		
		setSize(600, 400);
		setModal(true);
		
		okButton.addActionListener(new ActionListener() {			
			public void actionPerformed(ActionEvent event) {
				okButtonCallback(event);
			}
		});
		
		cancelButton.addActionListener(new ActionListener() {		
			public void actionPerformed(ActionEvent event) {
				cancelButtonCallback(event);
			}
		});
		
		calculateButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				calculateButtonCallback(event);
			}
		});
		
		tourLeaderComboBox.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				JComboBox cb = (JComboBox) e.getSource();
				Person p = (Person) cb.getSelectedItem();
				Integer age = p.getAge();
				tourLeaderAgeLabel.setText("Age: " + age.toString());				
			}		
		});
		
		asstTourLeaderComboBox.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				JComboBox cb = (JComboBox) e.getSource();
				Person p = (Person) cb.getSelectedItem();
				Integer age = p.getAge();
				asstTourLeaderAgeLabel.setText("Age: " + age.toString());				
			}		
		});
	}
	

	
	private void okButtonCallback(ActionEvent event) {
		Date departureDate = null;
		Date returnDate = null;
		
		// TODO:  Validate the data
		
		/* All the gyrations with the dates are because DateChooser
		 * returns java.util.Date and I'm working with java.sql.Date
		 * so I need to convert them.
		 */
		
		if (departureDateChooser.getDate() != null) {
			departureDate = new Date(departureDateChooser.getDate().getTime());
		}
		if (returnDateChooser.getDate() != null) {
			returnDate = new Date(returnDateChooser.getDate().getTime());
		}

		Person tourLeader = (Person) tourLeaderComboBox.getSelectedItem();
		Person asstTourLeader = (Person) asstTourLeaderComboBox.getSelectedItem();
		
		if (eventNameText.getText().length() == 0) {
			JOptionPane.showMessageDialog(null, "Event must have a name.", "Data Error", JOptionPane.ERROR_MESSAGE);
			return;
		}
		
		Integer travelMiles;
		try {
			travelMiles = new Integer(travelMilesText.getText());
		} catch (Exception e) {
			travelMiles = new Integer("0");
		}
		
		Event e = new Event(
				eventId,
				eventNameText.getText(),
				departureLocationText.getText(),
				destinationText.getText(),
				departureDate,
				returnDate,
				new Boolean(permitFiledCheckBox.isSelected()),
				new Boolean(swimmingCheckBox.isSelected()),
				new Boolean(boatingCheckBox.isSelected()),
				new Boolean(climbingCheckBox.isSelected()),
				new Boolean(flyingCheckBox.isSelected()),
				new Boolean(highAdventureCheckBox.isSelected()),
				travelMiles,
				tourLeader.getPersonId(),
				asstTourLeader.getPersonId());
		
		Object specialFormsArray[] = specialFormsListModel.toArray();
		for (Object formName : specialFormsArray) {
			e.addSpecialFormName((EventSpecialFormName) formName);
		}
		
		
		if (isNew) {
			DataManager.getInstance().addEvent(e);
		} else {
			DataManager.getInstance().updateEvent(e);
		}
		setVisible(false);
	}
	
	private void cancelButtonCallback(ActionEvent event) {
		setVisible(false);
	}
	
	private void calculateButtonCallback(ActionEvent event) {
		GoogleMaps gm = GoogleMaps.getInstance();
		
		gm.setStartLocation(departureLocationText.getText());
		gm.setEndLocation(destinationText.getText());
		
		Cursor hourglass = new Cursor(Cursor.WAIT_CURSOR);
		setCursor(hourglass);
		try {
			gm.submit();
			travelMilesText.setText(gm.getDistance().toString());
			String startAddress = gm.getStartAddress();
			String endAddress = gm.getEndAddress();
			JOptionPane.showMessageDialog(this, "Mileage calculated from " + startAddress + " to " + endAddress);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			JOptionPane.showMessageDialog(this, "Unable to determine distance.");
		}
		Cursor defaultCursor = new Cursor(Cursor.DEFAULT_CURSOR);
		setCursor(defaultCursor);
		
	}
	
	public void loadData(Event e) {
		if (e == null) {
			eventNameText.setText("");
			departureLocationText.setText("");
			destinationText.setText("");
			departureDateChooser.setDate(null);
			returnDateChooser.setDate(null);
			permitFiledCheckBox.setSelected(false);
			swimmingCheckBox.setSelected(false);
			boatingCheckBox.setSelected(false);
			climbingCheckBox.setSelected(false);
			flyingCheckBox.setSelected(false);
			highAdventureCheckBox.setSelected(false);
			travelMilesText.setText("");
			specialFormsListModel.clear();
			isNew = true;
			eventId = 0;
		} else {
			eventNameText.setText(e.getEventName());
			departureLocationText.setText(e.getDepartureLocation());
			destinationText.setText(e.getDestination());
			departureDateChooser.setDate(e.getDepartureDate());
			returnDateChooser.setDate(e.getReturnDate());
			permitFiledCheckBox.setSelected(e.getPermitFiled());
			swimmingCheckBox.setSelected(e.getSwimming());
			boatingCheckBox.setSelected(e.getBoating());
			climbingCheckBox.setSelected(e.getClimbing());
			flyingCheckBox.setSelected(e.getFlying());
			highAdventureCheckBox.setSelected(e.getHighAdventure());
			travelMilesText.setText(e.getTravelMiles().toString());		
			eventId = e.getEventId();
			specialFormsListModel.clear();
			for (EventSpecialFormName formName : e.getSpecialFormNames()) {
				specialFormsListModel.addElement(formName);
			}
			isNew = false;
		}
		
		LinkedList<Person> people = (LinkedList<Person>) DataManager.getInstance().getAllAdults();
		Person none = new Person(-1, "None", "", 0, null, null, null, "", false, null, "", "", "", "", "");
		
		tourLeaderComboBox.addItem(none);
		tourLeaderComboBox.setSelectedItem(none);
		
		asstTourLeaderComboBox.addItem(none);
		asstTourLeaderComboBox.setSelectedItem(none);
		
		for (Person p : people) {
			tourLeaderComboBox.addItem(p);
			if (e != null) {
				if (p.getPersonId() == e.getLeaderId()) {
					tourLeaderComboBox.setSelectedItem(p);
					Integer age = p.getAge();
					tourLeaderAgeLabel.setText("Age: " + age.toString());	
				}
			}
			
			asstTourLeaderComboBox.addItem(p);
			if (e != null) {
				if (p.getPersonId() == e.getAsstLeaderId()) {
					asstTourLeaderComboBox.setSelectedItem(p);
					Integer age = p.getAge();
					asstTourLeaderAgeLabel.setText("Age: " + age.toString());	
				}
			}
		}
		
	}
}
